﻿namespace LiteBlog.Controllers
{
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Web.Mvc;
    using LiteBlog.Common;
    using LiteBlog.Models;
    using LiteBlog.Components;
    using LiteBlog.Controllers.Filters;
    using LiteBlog.Common.Entities;
    using System.Web.Script.Serialization;
    using LiteBlog.Common.Enums;
    using LiteBlog.Components.Contracts;
    using LiteBlog.Components.Enums;
    using LiteBlog.Controllers.Helpers;
    using LiteBlog.Common.Components;
    using LiteBlog.Controllers.Contracts;


    public class CategoryController : CompController<Category, string>, ICategoryController
    {
        private ICategoryComp _categoryComp = null;
        private IBlogComp _blogComp;
        private IPostComp _postComp;
        private IAuthorComp _authorComp;

        public IBlogComp BlogComponent
        {
            get
            {
                return _blogComp;
            }
        }
        public IPostComp PostComponent
        {
            get
            {
                return _postComp;
            }
        }

        public IAuthorComp AuthorComponent
        {
            get
            {
                return _authorComp;
            }
        }


        public ICategoryComp CategoryComponent
        {
            get
            {
                return _categoryComp;
            }
        }

        public CategoryController(ICategoryComp categoryComp, 
            IBlogComp blogComp, 
            IPostComp postComp, 
            IAuthorComp authorComp,
            ISettingsComp settingsComp, 
            ICacheComp cacheComp) 
            : base(categoryComp, settingsComp, cacheComp)
        {
            _categoryComp = categoryComp;
            _blogComp = blogComp;
            _postComp = postComp;
            _authorComp = authorComp;
        }

        public override ActionResult Create(Category model)
        {
            return base.Create(model);
        }

        public override ActionResult Update(string olid, Category model)
        {
            return base.Update(olid, model);
        }

        public override ActionResult Delete(string id)
        {
            return base.Delete(id);
        }

        public override ActionResult Manage()
        {
            return base.Manage();
        }

        [HttpPost]
        [Authorize]
        [AjaxExceptionFilter]
        public ActionResult Reorder(string order)
        {
            string[] ids = order.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            for (int idx = 0; idx < ids.Length; idx++)
            {
                var id = ids[idx];
                var category = _component.Get(id);
                category.Order = idx + 1;
                _component.Update(id, category);
            }
            return Json(new ResultModel { Result = true });
        }


        [CategoryNotFoundFilter(Order = 1)]
        [CrawlerFilterForPosts(Order = 2)]
        [PageExceptionFilter]
        public ActionResult Index(string id, int? page)
        {
            var postInfos = BlogComponent.GetPostsByCategory(id);
            var postCollectionModel = new PostCollectionModel();

            var settings = GetSettings();
            int pageSize = settings.PostCount;
            page = page ?? 1;
            postCollectionModel.PageCount = postInfos.Count / pageSize + ((postInfos.Count % pageSize == 0) ? 0 : 1);
            page = Math.Min(page.Value, postCollectionModel.PageCount);
            int skip = (page.Value - 1) * pageSize;
            var posts = new List<Post>();
            foreach (var postInfo in postInfos.Skip(skip).Take(pageSize))
            {
                var post = PostComponent.Load(postInfo.FileID);
                DisplayHelper.SetDisplayTime(post);
                posts.Add(post);
            }
            postCollectionModel.PostCollection = posts;
            postCollectionModel.Page = page.Value;
            postCollectionModel.FilterId = id;
            postCollectionModel.FilterName = RouteData.Values["categoryName"].ToString();
            postCollectionModel.UrlType = UrlType.Category;
            // passing posts to CrawlerFilter
            RouteData.Values["posts"] = postCollectionModel;

            if (User.Identity.IsAuthenticated)
            {
                postCollectionModel.Author = AuthorComponent.Get(User.Identity.Name);
            }
            return View("Index", GetSiteLayout(), postCollectionModel);
        }

        [HttpGet]
        [AjaxExceptionFilter]
        public ActionResult GetMore(string id, int page)
        {
            var postInfos = BlogComponent.GetPostsByCategory(id);
            var settings = GetSettings();
            int pageSize = settings.PostCount;
            int startIndex = page * pageSize;
            var posts = new List<Post>();
            foreach (var postInfo in postInfos.Skip(startIndex).Take(pageSize))
            {
                var post = PostComponent.Load(postInfo.FileID);
                DisplayHelper.SetDisplayTime(post);
                posts.Add(post);
            }
            var resultModel = new ResultModel();
            resultModel.Result = posts.Count > 0 ? true : false;
            var resultModelWithData = new ResultModelWithData<List<Post>>(resultModel, posts);
            return this.Json(resultModelWithData, JsonRequestBehavior.AllowGet);
        }

        [PageExceptionFilter]
        public ActionResult Widget()
        {
            var categories = _component.Get();
            return PartialView(categories);
        }

        [Authorize]
        [HttpGet]
        [PageExceptionFilter]
        public ActionResult Get()
        {
            return Json(_component.Get(), JsonRequestBehavior.AllowGet);
        }

        protected override string[] GetMessageParams(Category model)
        {
            return new string[] { model.CatID, model.Name };
        }

        public override void ResolveComponents()
        {

        }
    }
}